package com.tanhua.server.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.dubbo.config.annotation.Reference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tanhua.common.pojo.Question;
import com.tanhua.common.pojo.User;
import com.tanhua.common.pojo.UserInfo;
import com.tanhua.common.utils.UserThreadLocal;
import com.tanhua.dubbo.server.api.HuanXinApi;
import com.tanhua.dubbo.server.api.UserLikeApi;
import com.tanhua.dubbo.server.api.UserLocationApi;
import com.tanhua.dubbo.server.api.VisitorsApi;
import com.tanhua.dubbo.server.enums.HuanXinMessageType;
import com.tanhua.dubbo.server.pojo.RecommendUser;
import com.tanhua.dubbo.server.vo.PageInfo;
import com.tanhua.dubbo.server.vo.UserLocationVo;
import com.tanhua.server.vo.NearUserVo;
import com.tanhua.server.vo.TodayBest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class TanHuaService {
    @Reference(version = "1.0.0")
    private HuanXinApi huanXinApi;
    @Reference(version = "1.0.0")
    private VisitorsApi visitorsApi;
    @Reference(version = "1.0.0")
    private UserLocationApi userLocationApi;
    @Reference(version = "1.0.0")
    private UserLikeApi userLikeApi;
    @Autowired
    private IMService imService;
    @Autowired
    private RecommendUserService recommendUserService;
    @Autowired
    private UserInfoService userInfoService;
    @Autowired
    private QuestionService questionService;
    @Value("${tanhua.default.recommend.users}")
    private String defaultRecommendUsers;

    /**
     * 查询个⼈主⻚的个⼈信息
     *
     * @param userId 用户id
     * @return
     */
    public TodayBest queryUserInfo(Long userId) {
        // 查询用户基本信息
        UserInfo userInfo = this.userInfoService.queryUserInfoByUserId(userId);
        if (ObjectUtil.isEmpty(userInfo)) {
            return null;
        }

        // 查询我与用户的缘分值
        User user = UserThreadLocal.get();
        Long score = recommendUserService.queryScore(userId, user.getId());

        // 封装数据
        TodayBest todayBest = new TodayBest();
        todayBest.setId(userInfo.getId()); // 主键id
        todayBest.setAvatar(userInfo.getLogo()); // 头像
        todayBest.setNickname(userInfo.getNickName()); // 昵称
        todayBest.setGender(userInfo.getSex().toString().toLowerCase()); // 性别【小写 man woman】
        todayBest.setAge(userInfo.getAge()); // 年龄
        todayBest.setTags(StrUtil.splitToArray(userInfo.getTags(), ",")); // 标签
        todayBest.setFateValue(score); // 缘分值

        // 记录来访用户信息
        this.visitorsApi.saveVisitor(userId, user.getId(), "个人主页");

        return todayBest;
    }

    /**
     * 查询陌生人问题
     *
     * @param userId 用户id
     * @return
     */
    public String queryQuestion(Long userId) {
        Question question = this.questionService.queryQuestion(userId);
        if (ObjectUtil.isNotEmpty(question)) {
            return question.getTxt();
        }
        return "骑砍2、空洞骑士、GTA5、大嫖客、巫师3......是说，你拿什么比？";
    }


    /**
     * 回复陌⽣⼈问题
     *
     * @param userId 用户id
     * @param reply  回复内容
     * @return
     */
    public Boolean replyQuestion(Long userId, String reply) {
        User user = UserThreadLocal.get();
        UserInfo userInfo = this.userInfoService.queryUserInfoByUserId(user.getId());

        // 构建消息内容
        Map<String, Object> msg = new HashMap<>();
        msg.put("userId", user.getId());
        msg.put("huanXinId", "HX_" + user.getId());
        msg.put("nickname", userInfo.getNickName());
        msg.put("strangerQuestion", this.queryQuestion(userId));
        msg.put("reply", reply);

        // 发送环信消息
        return this.huanXinApi.sendMsgFromAdmin("HX_" + userId, HuanXinMessageType.TXT, JSONUtil.toJsonStr(msg));

    }


    /**
     * 根据条件搜索附近用户
     *
     * @param gender   性别
     * @param distance 距离
     * @return
     */
    public List<NearUserVo> queryNearUser(String gender, Double distance) {
        /* 分析：先查询当前用户的位置，根据该位置作为范围中心，进行范围查询，最后再对数据进行封装返回 */

        /* 一、查询当前用户的位置 */
        User user = UserThreadLocal.get();
        // 查询用户位置
        UserLocationVo userLocationVo = this.userLocationApi.queryUserLocationByUserId(user.getId());


        /* 二、范围查询 */
        PageInfo<UserLocationVo> pageInfo = this.userLocationApi.queryUserFromLocation(userLocationVo.getLongitude(), // 经度
                userLocationVo.getLatitude(), // 纬度
                distance, // 半径
                1, 50);// 分页参数 【前50条】

        List<UserLocationVo> records = pageInfo.getRecords();
        if (CollUtil.isEmpty(records)) {
            // 没有查询到，返回空集合
            return Collections.emptyList();
        }


        /* 三、对范围查询的数据进行过滤 */
        // 获取所有查询到的用户id
        List<Object> userIdList = CollUtil.getFieldValues(records, "userId");

        // 构建查询条件
        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("user_id", userIdList);
        if (StrUtil.equalsAnyIgnoreCase(gender, "man")) {
            queryWrapper.eq("sex", 1);
        } else if (StrUtil.equalsAnyIgnoreCase(gender, "woman")) {
            queryWrapper.eq("sex", 2);
        }

        // 查询
        List<UserInfo> userInfoList = this.userInfoService.queryUserInfoByQueryWrapper(queryWrapper);

        List<NearUserVo> nearUserVoList = new ArrayList<>();
        NearUserVo nearUserVo = null;
        for (UserInfo userInfo : userInfoList) {
            // 排除⾃⼰
            if (userInfo.getUserId() == user.getId()) {
                continue;
            }
            nearUserVo = new NearUserVo();
            nearUserVo.setUserId(userInfo.getUserId()); // 用户id
            nearUserVo.setAvatar(userInfo.getLogo()); // 头像
            nearUserVo.setNickname(userInfo.getNickName()); // 昵称

            nearUserVoList.add(nearUserVo);
        }

        return nearUserVoList;
    }

    /**
     * 查询推荐卡片列表，从推荐列表中随机选取10个用户
     *
     * @return
     */
    public List<TodayBest> queryCardsList() {
        User user = UserThreadLocal.get();
        int count = 50;

        // 查询到的50条数据，并不是用来直接展现，需要从这50条数据中随机返回一些数据
        List<RecommendUser> recommendUserList = this.recommendUserService.queryCardList(user.getId(), count);
        List<Object> recommendUserIdList = CollUtil.getFieldValues(recommendUserList, "userId");

        if (CollUtil.isEmpty(recommendUserList)) {
            // 没有查询到推荐卡片，使用系统默认推荐用户id
            recommendUserIdList.addAll(StrUtil.split(this.defaultRecommendUsers, ","));
        }

        // 从推荐用户卡片中随机不重复挑选10张作为展示
        int max = Math.min(10, recommendUserIdList.size());
        List<Object> randomUserIdList = new ArrayList<>();
        List<Integer> randomNumList = new ArrayList<>();

        while (randomUserIdList.size() < max) {
            int randomInt = RandomUtil.randomInt(0, recommendUserIdList.size());
            if (!randomNumList.contains(randomInt)) {
                randomNumList.add(randomInt);
                randomUserIdList.add(recommendUserIdList.get(randomInt));
            }
        }

        // 查询推荐用户基本信息
        List<UserInfo> userInfoList = this.userInfoService.queryUserInfoByUserIdList(randomUserIdList);

        // 封装数据返回
        List<TodayBest> todayBestList = new ArrayList<>();
        TodayBest todayBest = null;
        for (UserInfo userInfo : userInfoList) {
            todayBest = new TodayBest();
            todayBest.setId(userInfo.getUserId()); // 用户id
            todayBest.setAge(userInfo.getAge()); // 年龄
            todayBest.setAvatar(userInfo.getLogo()); // 头像
            todayBest.setGender(userInfo.getSex().name().toLowerCase()); // 性别
            todayBest.setNickname(userInfo.getNickName()); // 昵称
            todayBest.setTags(Convert.toStrArray(StrUtil.split(userInfo.getTags(), ','))); // 标签
            todayBest.setFateValue(0L); // 缘分值【没有用到，所以不用为其查询准确值】

            todayBestList.add(todayBest);
        }

        return todayBestList;
    }

    /**
     * 探花 喜欢
     *
     * @param likeUserId 喜欢用户的id
     * @return
     */
    public Boolean likeUser(Long likeUserId) {
        try {
            User user = UserThreadLocal.get();
            // 喜欢用户
            Boolean result = this.userLikeApi.likeUser(user.getId(), likeUserId);

            // 判断喜欢后，双方是否喜欢，喜欢的话需要自动成为好友
            if (result && this.userLikeApi.isMutualLike(user.getId(), likeUserId)) {
                // 添加好友
                return this.imService.contactUser(likeUserId);
            }
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return false;
    }

    /**
     * 探花 不喜欢
     *
     * @param notLikeUserId 不喜欢用户的id
     * @return
     */
    public Boolean notLikeUser(Long notLikeUserId) {
        /* 分析：不喜欢是存在Redis中，所以直接调用dubbo服务操作Redis即可 */
        try {
            User user = UserThreadLocal.get();
            return this.userLikeApi.notLikeUser(user.getId(), notLikeUserId);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return false;
    }
}
